/**
 * @file DR16.hpp
 * @author yssickjgd (1345578933@qq.com)
 * @brief DR16遥控器
 * @version 0.1
 * @date 2022-05-26
 *
 * @copyright USTC-RoboWalker (c) 2022
 *
 */

#ifndef DR16_H
#define DR16_H

/* Includes ------------------------------------------------------------------*/

#include <limits.h>
#include <string.h>
#include "drv_uart.h"

/* Exported macros -----------------------------------------------------------*/

//摇杆偏移量
#define ROCKER_OFFSET (1024.0f)
//摇杆总刻度
#define ROCKER_NUM (660.0f)

//拨动开关位置
#define SWITCH_UP (1)
#define SWITCH_DOWN (2)
#define SWITCH_MIDDLE (3)

//按键开关位置
#define KEY_FREE (0)
#define KEY_PRESSED (1)

//键位宏定义
#define KEY_W 0
#define KEY_S 1
#define KEY_A 2
#define KEY_D 3
#define KEY_SHIFT 4
#define KEY_CTRL 5
#define KEY_Q 6
#define KEY_E 7
#define KEY_R 8
#define KEY_F 9
#define KEY_G 10
#define KEY_Z 11
#define KEY_X 12
#define KEY_C 13
#define KEY_V 14
#define KEY_B 15

/* Exported types ------------------------------------------------------------*/

/**
 * @brief 遥控器状态
 *
 */
enum Enum_DR16_Status
{
    DR16_Status_DISABLE = 0,
    DR16_Status_ENABLE,
};

/**
 * @brief 拨动开关状态
 *
 */
enum Enum_DR16_Switch_Status
{
    DR16_Switch_Status_UP = 0,
    DR16_Switch_Status_TRIG_UP_MIDDLE,
    DR16_Switch_Status_TRIG_MIDDLE_UP,
    DR16_Switch_Status_MIDDLE,
    DR16_Switch_Status_TRIG_MIDDLE_DOWN,
    DR16_Switch_Status_TRIG_DOWN_MIDDLE,
    DR16_Switch_Status_DOWN,
};

/**
 * @brief 按键状态
 *
 */
enum Enum_DR16_Key_Status
{
    DR16_Key_Status_FREE = 0,
    DR16_Key_Status_TRIG_FREE_PRESSED,
    DR16_Key_Status_TRIG_PRESSED_FREE,
    DR16_Key_Status_PRESSED,
};

/**
 * @brief DR16源数据
 *
 */
struct Struct_DR16_UART_Data
{
    uint64_t Channel_0 : 11;
    uint64_t Channel_1 : 11;
    uint64_t Channel_2 : 11;
    uint64_t Channel_3 : 11;
    uint64_t Switch_2 : 2;
    uint64_t Switch_1 : 2;
    int16_t Mouse_X;
    int16_t Mouse_Y;
    int16_t Mouse_Z;
    uint64_t Mouse_Left_Key : 8;
    uint64_t Mouse_Right_Key : 8;
    uint64_t Keyboard_Key : 16;
    uint64_t Channel_Yaw : 11;
};

/**
 * @brief DR16接收的遥控器状态信息, 摇杆信息经过归一化到-1~1, 鼠标信息有待进一步标定
 *
 */
struct Struct_DR16_Data
{
    float Right_X;
    float Right_Y;
    float Left_X;
    float Left_Y;
    Enum_DR16_Switch_Status Left_Switch;
    Enum_DR16_Switch_Status Right_Switch;
    float Mouse_X;
    float Mouse_Y;
    float Mouse_Z;
    Enum_DR16_Key_Status Mouse_Left_Key;
    Enum_DR16_Key_Status Mouse_Right_Key;
    Enum_DR16_Key_Status Keyboard_Key[16];
    float Yaw;
};

class Class_DR16
{
public:
    void Init(UART_HandleTypeDef *__huart);

    Enum_DR16_Status Get_DR16_Status();
    float Get_Right_X();
    float Get_Right_Y();
    float Get_Left_X();
    float Get_Left_Y();
    Enum_DR16_Switch_Status Get_Left_Switch();
    Enum_DR16_Switch_Status Get_Right_Switch();
    float Get_Mouse_X();
    float Get_Mouse_Y();
    float Get_Mouse_Z();
    Enum_DR16_Key_Status Get_Mouse_Left_Key();
    Enum_DR16_Key_Status Get_Mouse_Right_Key();
    Enum_DR16_Key_Status Get_Keyboard_Key_W();
    Enum_DR16_Key_Status Get_Keyboard_Key_S();
    Enum_DR16_Key_Status Get_Keyboard_Key_A();
    Enum_DR16_Key_Status Get_Keyboard_Key_D();
    Enum_DR16_Key_Status Get_Keyboard_Key_Shift();
    Enum_DR16_Key_Status Get_Keyboard_Key_Ctrl();
    Enum_DR16_Key_Status Get_Keyboard_Key_Q();
    Enum_DR16_Key_Status Get_Keyboard_Key_E();
    Enum_DR16_Key_Status Get_Keyboard_Key_R();
    Enum_DR16_Key_Status Get_Keyboard_Key_F();
    Enum_DR16_Key_Status Get_Keyboard_Key_G();
    Enum_DR16_Key_Status Get_Keyboard_Key_Z();
    Enum_DR16_Key_Status Get_Keyboard_Key_X();
    Enum_DR16_Key_Status Get_Keyboard_Key_C();
    Enum_DR16_Key_Status Get_Keyboard_Key_V();
    Enum_DR16_Key_Status Get_Keyboard_Key_B();
    float Get_Yaw();

    void TIM_Alive_PeriodElapsedCallback();
    void UART_RxCpltCallback(uint8_t *Rx_Data);

protected:
    //初始化相关常量

    //绑定的UART编号
    UART_HandleTypeDef *huart;
    //接收缓冲区
    Struct_DR16_UART_Data *UART_Rx_Data;

    //常量

    //内部变量

    //前一时刻的遥控器状态信息
    Struct_DR16_UART_Data Pre_UART_Rx_Data;
    //当前时刻的遥控器接收flag
    uint32_t Flag;
    //前一时刻的遥控器接收flag
    uint32_t Pre_Flag;

    //读变量

    //遥控器状态
    Enum_DR16_Status DR16_Status = DR16_Status_DISABLE;
    // DR16对外接口信息
    Struct_DR16_Data Data;

    //写变量

    //读写变量

    //内部函数
    
    void Reset_UART_Rx_Data();
    void Judge_Switch(Enum_DR16_Switch_Status *Switch, uint8_t Status, uint8_t Pre_Status);
    void Judge_Key(Enum_DR16_Key_Status *Key, uint8_t Status, uint8_t Pre_Status);
    void Data_Process();
};

/* Exported variables --------------------------------------------------------*/

/* Exported function declarations --------------------------------------------*/

#endif

/************************ COPYRIGHT(C) USTC-ROBOWALKER **************************/
